package cn.lili.modules.order.cart.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.client.GoodsIndexClient;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dos.Wholesale;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsMarketEnum;
import cn.lili.modules.goods.entity.enums.SalesModeEnum;
import cn.lili.modules.member.client.RedPackUserClient;
import cn.lili.modules.member.client.UserAddressClient;
import cn.lili.modules.member.entity.dos.RedPackUser;
import cn.lili.modules.member.entity.dos.UserAddress;
import cn.lili.modules.order.cart.entity.dto.MemberCouponDTO;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.CartSceneEnum;
import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.cart.render.TradeBuilder;
import cn.lili.modules.order.order.entity.dto.CartParamsDTO;
import cn.lili.modules.order.order.entity.vo.ReceiptVO;
import cn.lili.modules.order.order.service.TradeService;
import cn.lili.modules.payment.client.WalletPointClient;
import cn.lili.modules.promotion.client.*;
import cn.lili.modules.promotion.entity.dos.KanjiaActivity;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dos.ReturnActivityUser;
import cn.lili.modules.promotion.entity.dto.search.KanjiaActivitySearchParams;
import cn.lili.modules.promotion.entity.dto.search.MemberCouponSearchParams;
import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams;
import cn.lili.modules.promotion.entity.enums.*;
import cn.lili.modules.promotion.entity.vos.PointsGoodsVO;
import cn.lili.modules.promotion.entity.vos.RedPackGoodsVO;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.store.client.StoreClient;
import com.alibaba.fastjson.JSON;
import com.api.PayApi;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 购物车业务层实现
 *
 * @author Chopper
 * @since 2020-03-23 12:29 下午
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CartHandler {

    static String errorMessage = "购物车异常，请稍后重试";

    private final TradeBuilder tradeBuilder;

    private final TradeService tradeService;

    private final UserAddressClient userAddressClient;

    private final PromotionsClient promotionsClient;

    private final KanjiaActivityClient kanjiaActivityClient;

    private final PromotionGoodsClient promotionGoodsClient;

    private final GoodsClient goodsClient;

    private final GoodsIndexClient goodsIndexClient;

    private final StoreClient storeClient;

    private final WalletPointClient walletPointClient;

    private final PayApi payApi;

    private final ReturnActivityClient returnActivityClient;

    private final RedPackUserClient redPackUserClient;

    private final RedPackGoodsClient redPackGoodsClient;

    /**
     * 购物车添加商品
     *
     * @param cartParamsDTO 参数
     */
    public void add(CartParamsDTO cartParamsDTO) {
        log.info("cartParamsDTO == {}", com.alibaba.fastjson.JSONObject.toJSONString(cartParamsDTO));
        String skuId = cartParamsDTO.getSkuId();
        CartSceneEnum cartSceneEnum = cartParamsDTO.cartSceneEnum();

        AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser());
        //购买数量大于0
        if (cartParamsDTO.getNum() <= 0) {
            throw new ServiceException(ResultCode.CART_NUM_ERROR);
        }

        try {
            //获取商品详情
            GoodsSku dataSku = checkGoods(skuId);

            //购物车方式购买需要保存之前的选择，其他方式购买，则直接抹除掉之前的记录
            TradeDTO tradeDTO;

            //立即购买则清空之前的立即购买栏
            if (cartParamsDTO.cartSceneEnum().equals(CartSceneEnum.BUY_NOW)) {
                tradeDTO = new TradeDTO(cartSceneEnum, currentUser);
            } else {
                //如果存在，则变更数量不做新增，否则新增一个商品进入集合
                tradeDTO = tradeBuilder.readDTO(cartSceneEnum);
            }

            log.info("=====carts:promotionType====={}", cartParamsDTO.getPromotionType());
            if (cartParamsDTO.getPromotionType() != null) {
                tradeDTO.setPromotionType(cartParamsDTO.getPromotionType());
            }

            //整笔交易规格商品
            List<CartSkuVO> cartSkuVOS = tradeDTO.getSkuList();
            //获取购物车中的商品
            CartSkuVO cartSkuVO = cartSkuVOS.stream().filter(i -> i.getGoodsSku().getId().equals(skuId)).findFirst().orElse(null);

            //ps 判定时间是因为商品再编辑sku时，会删除之前的sku，重新创建sku，保留skuid不变，所以这里判定创建时间
            //如果购物车中存在sku，且sku的创建时间等于最新获取数据中的sku，则修改数量
            if (cartSkuVO != null && dataSku.getCreateTime().equals(cartSkuVO.getGoodsSku().getCreateTime())) {
                //如果覆盖购物车中商品数量 则写入传入的库存，否则累加之前的库存
                cartSkuVO.setNum(Boolean.TRUE.equals(cartParamsDTO.getCover()) ? cartParamsDTO.getNum() :
                        cartSkuVO.getNum() + cartParamsDTO.getNum());
            }
            //购物车不存在商品
            else {
                //先清理一下 如果商品无效的话
                cartSkuVOS.remove(cartSkuVO);
                //购物车中不存在此商品，则新建立一个
                cartSkuVO = new CartSkuVO(dataSku);
                cartSkuVO.setNum(cartParamsDTO.getNum());
                cartSkuVOS.add(cartSkuVO);
            }

            cartSkuVO.setCartType(cartSceneEnum);
            //判定购物车商品库存
            this.checkSetGoodsQuantity(cartSkuVO, skuId, cartSkuVO.getNum());

            //检查促销信息
            this.checkGoodsPromotion(cartParamsDTO, cartSkuVO);


            cartSkuVO.setSubTotal(CurrencyUtil.mul(cartSkuVO.getPurchasePrice(), cartSkuVO.getNum()));
            //新加入的商品都是选中的
            cartSkuVO.setChecked(cartParamsDTO.getChecked() == null ? true : cartParamsDTO.getChecked());


            //检测商品类型是否为批发
            this.checkGoodsSaleModel(dataSku, tradeDTO.getSkuList());

            System.out.println(cartParamsDTO);

            // 设置分销商
            if(cartParamsDTO.getDistributionId() != null) {
                tradeDTO.setDistributionId(cartParamsDTO.getDistributionId());
            }

            //购物车添加缓存
            log.info("1213112");
            if (CollUtil.isNotEmpty(tradeDTO.getSkuList())) {
                tradeDTO.getSkuList().forEach(e -> {
                    e.setChecked(cartParamsDTO.getChecked() == null ? true : cartParamsDTO.getChecked());
                });
            }
            if (CollUtil.isNotEmpty(tradeDTO.getCartList())) {
                tradeDTO.getCartList().forEach(e -> {
                    e.setChecked(cartParamsDTO.getChecked() == null ? true : cartParamsDTO.getChecked());
                });
            }
            log.info("add  tradeDTO == {}", tradeDTO);
            tradeBuilder.resetTradeDTO(tradeDTO);
            log.info("end  try ===");
        } catch (ServiceException serviceException) {
            log.error("serviceException = ", serviceException);
            throw serviceException;
        } catch (Exception e) {
            log.error("购物车渲染异常 = ", e);
            e.printStackTrace();
            throw new ServiceException(errorMessage);
        }

    }


    /**
     * 更新选中状态
     *
     * @param skuId   要写入的skuId
     * @param checked 是否选中
     */
    public void checked(String way, String skuId, Boolean checked) {
        TradeDTO tradeDTO = tradeBuilder.readDTO(CartSceneEnum.getCartType(way));

        List<CartSkuVO> cartSkuVOS = tradeDTO.getSkuList();
        for (CartSkuVO cartSkuVO : cartSkuVOS) {
            if (cartSkuVO.getGoodsSku().getId().equals(skuId)) {
                cartSkuVO.setChecked(checked);
            }
        }
        tradeBuilder.resetTradeDTO(tradeDTO);
    }


    /**
     * 更新某个店铺的所有商品的选中状态
     *
     * @param storeId 店铺Id
     * @param checked 是否选中
     */
    public void checkedStore(String way, String storeId, Boolean checked) {
        TradeDTO tradeDTO = tradeBuilder.readDTO(CartSceneEnum.getCartType(way));

        List<CartSkuVO> cartSkuVOS = tradeDTO.getSkuList();
        for (CartSkuVO cartSkuVO : cartSkuVOS) {
            if (cartSkuVO.getStoreId().equals(storeId)) {
                cartSkuVO.setChecked(checked);
            }
        }
        tradeBuilder.resetTradeDTO(tradeDTO);
    }


    /**
     * 更新全部的选中状态
     *
     * @param checked 是否选中
     */
    public void checkedAll(String way, Boolean checked) {
        TradeDTO tradeDTO = tradeBuilder.readDTO(CartSceneEnum.getCartType(way));

        List<CartSkuVO> cartSkuVOS = tradeDTO.getSkuList();
        for (CartSkuVO cartSkuVO : cartSkuVOS) {
            cartSkuVO.setChecked(checked);
        }
        tradeBuilder.resetTradeDTO(tradeDTO);
    }


    /**
     * 批量删除
     *
     * @param skuIds 要写入的skuIds
     */
    public void delete(String way, String[] skuIds) {
        TradeDTO tradeDTO = tradeBuilder.readDTO(CartSceneEnum.getCartType(way));
        List<CartSkuVO> cartSkuVOS = tradeDTO.getSkuList();
        List<CartSkuVO> deleteVos = new ArrayList<>();
        for (CartSkuVO cartSkuVO : cartSkuVOS) {
            for (String skuId : skuIds) {
                if (cartSkuVO.getGoodsSku().getId().equals(skuId)) {
                    deleteVos.add(cartSkuVO);
                }
            }
        }
        cartSkuVOS.removeAll(deleteVos);
        tradeBuilder.resetTradeDTO(tradeDTO);
    }

    /**
     * 获取可使用的优惠券数量
     *
     * @param way 购物车购买：CART/立即购买：BUY_NOW/拼团购买：PINTUAN / 积分购买：POINT
     * @return 可使用的优惠券数量
     */

    public Long getCanUseCoupon(String way) {
        TradeDTO tradeDTO = tradeBuilder.readDTO(CartSceneEnum.getCartType(way));
        long count = 0L;
        double totalPrice = tradeDTO.getSkuList().stream().mapToDouble(i -> i.getPurchasePrice() * i.getNum()).sum();
        if (!tradeDTO.getSkuList().isEmpty()) {
            List<String> ids =
                    tradeDTO.getSkuList().stream().filter(i -> Boolean.TRUE.equals(i.getChecked())).map(i -> i.getGoodsSku().getId()).collect(Collectors.toList());

            List<EsGoodsIndex> esGoodsList = goodsIndexClient.getEsGoodsBySkuIds(ids);
            for (EsGoodsIndex esGoodsIndex : esGoodsList) {
                if (esGoodsIndex != null && esGoodsIndex.getPromotionMap() != null && !esGoodsIndex.getPromotionMap().isEmpty()) {
                    List<String> couponIds =
                            esGoodsIndex.getPromotionMap().keySet().stream().filter(i -> i.contains(PromotionTypeEnum.COUPON.name())).map(i -> i.substring(i.lastIndexOf("-") + 1)).collect(Collectors.toList());
                    if (!couponIds.isEmpty()) {
                        List<MemberCoupon> currentGoodsCanUse = promotionsClient.getCurrentGoodsCanUse(tradeDTO.getMemberId(), couponIds, totalPrice);
                        count = currentGoodsCanUse.size();
                    }
                }
            }

            List<String> storeIds = new ArrayList<>();
            for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) {
                if (!storeIds.contains(cartSkuVO.getStoreId())) {
                    storeIds.add(cartSkuVO.getStoreId());
                }
            }

            //获取可操作的优惠券集合
            List<MemberCoupon> allScopeMemberCoupon = promotionsClient.getAllScopeMemberCoupon(tradeDTO.getMemberId(), storeIds);
            if (allScopeMemberCoupon != null && !allScopeMemberCoupon.isEmpty()) {
                //过滤满足消费门槛
                count += allScopeMemberCoupon.stream().filter(i -> i.getConsumeThreshold() <= totalPrice).count();
            }
        }
        return count;
    }

    /**
     * 选择收货地址
     *
     * @param shippingAddressId 收货地址id
     * @param way               购物车类型
     */
    public void shippingAddress(String way, String shippingAddressId) {

        //默认购物车
        CartSceneEnum cartSceneEnum = CartSceneEnum.getCartType(way);

        TradeDTO tradeDTO = tradeBuilder.readDTO(cartSceneEnum);
        UserAddress userAddress = userAddressClient.getAddressById(shippingAddressId);
        tradeDTO.setUserAddress(userAddress);
        if (StringUtils.isNotEmpty(tradeDTO.getAuthName())) {
            tradeDTO.getUserAddress().setName(tradeDTO.getAuthName());
        }
        tradeBuilder.resetTradeDTO(tradeDTO);
    }

    /**
     * 选择发票
     *
     * @param way       购物车类型
     * @param receiptVO 发票信息
     */
    public void shippingReceipt(String way, ReceiptVO receiptVO) {
        CartSceneEnum cartSceneEnum = CartSceneEnum.getCartType(way);
        TradeDTO tradeDTO = tradeBuilder.readDTO(cartSceneEnum);
        tradeDTO.setNeedReceipt(true);
        tradeDTO.setReceiptVO(receiptVO);
        tradeBuilder.resetTradeDTO(tradeDTO);
    }

    /**
     * 选择配送方式
     *
     * @param storeId        店铺id
     * @param deliveryMethod 配送方式
     * @param way            购物车类型
     */
    public void shippingMethod(String storeId, String deliveryMethod, String way) {
        CartSceneEnum cartSceneEnum = CartSceneEnum.getCartType(way);

        TradeDTO tradeDTO = tradeBuilder.readDTO(cartSceneEnum);
        for (CartVO cartVO : tradeDTO.getCartList()) {
            if (cartVO.getStoreId().equals(storeId)) {
                cartVO.setDeliveryMethod(DeliveryMethodEnum.valueOf(deliveryMethod).name());
            }
        }
        tradeBuilder.resetTradeDTO(tradeDTO);
    }

    /**
     * 获取配送方式列表
     *
     * @param way 购物车类型
     * @return 配送方式列表
     */
    public List<String> shippingMethodList(String way) {
        CartSceneEnum cartSceneEnum = CartSceneEnum.getCartType(way);

        List<String> list = new ArrayList<>();
        list.add(DeliveryMethodEnum.LOGISTICS.name());
//        TradeDTO tradeDTO = tradeBuilder.buildChecked(cartSceneEnum);
//        if (tradeDTO.getCartList().size() == 1) {
//            for (CartVO cartVO : tradeDTO.getCartList()) {
//                Store store = storeClient.getStore(cartVO.getStoreId());
//                if (store.getEnablePickup() != null && store.getEnablePickup()) {
//                    list.add(DeliveryMethodEnum.SELF_PICK_UP.name());
//                }
//            }
//        }
//
//        //如果交易中有供应商物品，同样无法提供自提。供应商无法提供自提业务。
//        if (tradeDTO.getCheckedSkuList().stream().anyMatch(j -> j.getGoodsSku().getIsProxyGoods())) {
//            list.remove(DeliveryMethodEnum.SELF_PICK_UP.name());
//        }

        return list;
    }

    /**
     * 获取购物车商品数量
     *
     * @param cartTypeEnum 购物车类型
     * @return 购物车商品数量
     */
    public int getCartNum(String cartTypeEnum) {
        TradeDTO tradeDTO = tradeBuilder.readDTO(CartSceneEnum.getCartType(cartTypeEnum));
        return tradeDTO.getSkuList().size();
    }

    /**
     * 选择优惠券
     *
     * @param couponId 优惠券id
     * @param way      购物车类型
     * @param use      true使用 false 弃用
     */
    public void selectCoupon(String way, String couponId, boolean use) {
        AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser());
        //获取购物车，然后重新写入优惠券
        CartSceneEnum cartSceneEnum = CartSceneEnum.getCartType(way);
        TradeDTO tradeDTO = tradeBuilder.readDTO(cartSceneEnum);

        MemberCouponSearchParams searchParams = new MemberCouponSearchParams();
        searchParams.setMemberCouponStatus(MemberCouponStatusEnum.NEW.name());
        searchParams.setMemberId(currentUser.getExtendId());
        searchParams.setId(couponId);
        MemberCoupon memberCoupon = promotionsClient.getMemberCoupon(searchParams);
        if (memberCoupon == null) {
            throw new ServiceException(ResultCode.COUPON_EXPIRED);
        }
        //使用优惠券 与否
        if (use) {
            log.info("=======ReturnActivityUser========{}", JSON.toJSONString(tradeDTO.getReturnActivityUser()));
            if (null != tradeDTO.getReturnActivityUser()) {
                throw new ServiceException("全返券和优惠券不能同时使用");
            }
            this.useCoupon(tradeDTO, memberCoupon);
        } else {
            if (Boolean.TRUE.equals(memberCoupon.getPlatformFlag())) {
                tradeDTO.setPlatformCoupon(null);
            } else {
                tradeDTO.getStoreCoupons().remove(memberCoupon.getStoreId());
            }
        }
        tradeBuilder.resetTradeDTO(tradeDTO);
    }

    /**
     * 选择F分抵扣
     * @param way
     * @param use
     */
    public void selectFmoney(String way, boolean use){
        // 查询到当前用户
//        AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser());

        // 查询缓存购物车
        CartSceneEnum cartSceneEnum = CartSceneEnum.getCartType(way);
        TradeDTO tradeDTO = tradeBuilder.readDTO(cartSceneEnum);

//        UserRes res = payApi.getUserMoney(currentUser.getOpenId());

        // 如果余额足够的话则
        tradeDTO.setUseFmoney(use);
        tradeBuilder.resetTradeDTO(tradeDTO);
    }

    /**
     * 选择全返卷抵扣
     * @param way
     * @param returnActivityUserId
     */
    public void selectReturnActivity(String way, String returnActivityUserId, boolean used){
        //查询缓存购物车
        CartSceneEnum cartSceneEnum = CartSceneEnum.getCartType(way);
        TradeDTO tradeDTO = tradeBuilder.readDTO(cartSceneEnum);
        if(used){
            log.info("=======PlatformCoupon========{}", JSON.toJSONString(tradeDTO.getPlatformCoupon()));
            if (null != tradeDTO.getPlatformCoupon()) {
                throw new ServiceException("全返券和优惠券不能同时使用");
            }
            //校验全返卷是否合法
            ReturnActivityUser returnActivityUser = returnActivityClient.getById(returnActivityUserId);
            if(returnActivityUser == null){
                throw new ServiceException("全返卷不存在");
            }
            if(!ReturnActivityUserStatusEnum.UN_TAKE_EFFECT.getCode().equals(returnActivityUser.getStatus())){
                throw new ServiceException("全返卷未生效");
            }
            if(!ReturnActivityUserUseEnum.UN_USE.getCode().equals(returnActivityUser.getUseStatus())){
                throw new ServiceException("全返卷已使用或已过期");
            }

            //设置全返卷ID
            tradeDTO.setReturnActivityUser(returnActivityUser);

        }else{
            tradeDTO.setReturnActivityUser(null);
        }
        //刷新tradeDTO
        tradeBuilder.resetTradeDTO(tradeDTO);
    }


    /**
     * 使用优惠券判定
     *
     * @param tradeDTO     交易对象
     * @param memberCoupon 会员优惠券
     */
    private void useCoupon(TradeDTO tradeDTO, MemberCoupon memberCoupon) {

        if (Boolean.TRUE.equals(memberCoupon.getPlatformFlag())) {
            tradeDTO.setPlatformCoupon(new MemberCouponDTO(memberCoupon));
        } else {
            tradeDTO.getStoreCoupons().put(memberCoupon.getStoreId(), new MemberCouponDTO(memberCoupon));
        }
    }

    /**
     * 获取可以使用优惠券的商品信息
     *
     * @param memberCoupon 用于计算优惠券结算详情
     * @param tradeDTO     购物车信息
     * @return 是否可以使用优惠券
     */
    private List<CartSkuVO> checkCoupon(MemberCoupon memberCoupon, TradeDTO tradeDTO) {
        List<CartSkuVO> cartSkuVOS;
        //如果是店铺优惠券，判定的内容
        if (Boolean.FALSE.equals(memberCoupon.getPlatformFlag())) {
            cartSkuVOS = tradeDTO.getSkuList().stream().filter(i -> i.getStoreId().equals(memberCoupon.getStoreId())).collect(Collectors.toList());
        }
        //否则为平台优惠券，筛选商品为全部商品
        else {
            cartSkuVOS = tradeDTO.getSkuList();
        }

        //当初购物车商品中是否存在符合优惠券条件的商品sku
        if (memberCoupon.getScopeType().equals(PromotionsScopeTypeEnum.ALL.name())) {
            return cartSkuVOS;
        } else if (memberCoupon.getScopeType().equals(PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name())) {
            //分类路径是否包含
            return cartSkuVOS.stream().filter(i -> CharSequenceUtil.contains(memberCoupon.getScopeId(), i.getGoodsSku().getCategoryPath())).collect(Collectors.toList());
        } else if (memberCoupon.getScopeType().equals(PromotionsScopeTypeEnum.PORTION_GOODS.name())) {
            //范围关联ID是否包含
            return cartSkuVOS.stream().filter(i -> CharSequenceUtil.contains(memberCoupon.getScopeId(), i.getGoodsSku().getId())).collect(Collectors.toList());
        } else if (memberCoupon.getScopeType().equals(PromotionsScopeTypeEnum.PORTION_SHOP_CATEGORY.name())) {
            //店铺分类路径是否包含
            return cartSkuVOS.stream().filter(i -> CharSequenceUtil.contains(memberCoupon.getScopeId(), i.getGoodsSku().getStoreCategoryPath())).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 检测购物车
     *
     * @param cartSkuVO SKUVO
     * @param skuId     SkuId
     * @param num       数量
     */
    private void checkCart(CartSkuVO cartSkuVO, String skuId, Integer num) {
        if (cartSkuVO.getPromotionTypeEnum() == null) {
            return;
        }

        this.checkSetGoodsQuantity(cartSkuVO, skuId, num);
        //拼团判定
        if (cartSkuVO.getPromotionTypeEnum().equals(PromotionTypeEnum.PINTUAN)) {
            //砍价判定
            checkPintuan(cartSkuVO);
        } else if (cartSkuVO.getPromotionTypeEnum().equals(PromotionTypeEnum.KANJIA)) {
            //检测购物车的数量
            checkKanjia(cartSkuVO);
        } else if (cartSkuVO.getPromotionTypeEnum().equals(PromotionTypeEnum.POINTS_GOODS)) {
            //检测购物车的数量
            checkPoint(cartSkuVO);
        } else if (cartSkuVO.getPromotionTypeEnum().equals(PromotionTypeEnum.RED_PACK_GOODS)) {
            //检测购物车的数量
            checkRedPack(cartSkuVO);
        }
    }


    /**
     * 检测商品类型是否为批发
     *
     * @param dataSku
     * @param cartSkuVOS
     */
    private void checkGoodsSaleModel(GoodsSku dataSku, List<CartSkuVO> cartSkuVOS) {
        if (dataSku.getSalesModel().equals(SalesModeEnum.WHOLESALE.name())) {
            int numSum = 0;
            List<CartSkuVO> sameGoodsIdSkuList =
                    cartSkuVOS.stream().filter(i -> i.getGoodsSku().getGoodsId().equals(dataSku.getGoodsId())).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(sameGoodsIdSkuList)) {
                numSum += sameGoodsIdSkuList.stream().mapToInt(CartSkuVO::getNum).sum();
            }
            //匹配批发商品规则
            Wholesale match = goodsClient.getMatchWholesale(dataSku.getGoodsId(), numSum);
            if (match != null) {
                sameGoodsIdSkuList.forEach(i -> {
                    i.setPurchasePrice(match.getPrice());
                    i.setSubTotal(CurrencyUtil.mul(i.getPurchasePrice(), i.getNum()));
                });
            }
        }
    }

    /**
     * 校验拼团信息
     *
     * @param cartSkuVO 购物车信息
     */
    private void checkPintuan(CartSkuVO cartSkuVO) {
        //拼团活动，需要对限购数量进行判定
        //获取拼团信息
        if (cartSkuVO.getPromotionMap() != null && !cartSkuVO.getPromotionMap().isEmpty()) {
            Optional<Map.Entry<String, Object>> pintuanPromotions =
                    cartSkuVO.getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst();
            if (pintuanPromotions.isPresent()) {
                JSONObject promotionsObj = JSONUtil.parseObj(pintuanPromotions.get().getValue());
                //写入拼团信息
                cartSkuVO.setPromotionId(promotionsObj.get("id").toString());
                //检测拼团限购数量
                Integer limitNum = promotionsObj.get("limitNum", Integer.class);
                if (limitNum != 0 && cartSkuVO.getNum() > limitNum) {
                    throw new ServiceException(ResultCode.CART_PINTUAN_LIMIT_ERROR);
                }
            }
        }
    }

    /**
     * 校验砍价信息
     *
     * @param cartSkuVO 购物车信息
     */
    private void checkKanjia(CartSkuVO cartSkuVO) {
        if (cartSkuVO.getPromotionMap() != null && !cartSkuVO.getPromotionMap().isEmpty()) {
            Optional<Map.Entry<String, Object>> kanjiaPromotions =
                    cartSkuVO.getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.KANJIA.name())).findFirst();
            if (kanjiaPromotions.isPresent()) {
                JSONObject promotionsObj = JSONUtil.parseObj(kanjiaPromotions.get().getValue());
                //查找当前会员的砍价商品活动
                KanjiaActivitySearchParams kanjiaActivitySearchParams = new KanjiaActivitySearchParams();
                kanjiaActivitySearchParams.setKanjiaActivityGoodsId(promotionsObj.get("id", String.class));
                kanjiaActivitySearchParams.setMemberId(UserContext.getCurrentUser().getExtendId());
                kanjiaActivitySearchParams.setStatus(KanJiaStatusEnum.SUCCESS.name());
                KanjiaActivity kanjiaActivity = kanjiaActivityClient.getKanjiaActivity(kanjiaActivitySearchParams);

                //校验砍价活动是否满足条件
                //判断发起砍价活动
                if (kanjiaActivity == null) {
                    throw new ServiceException(ResultCode.KANJIA_ACTIVITY_NOT_FOUND_ERROR);
                    //判断砍价活动是否已满足条件
                } else if (!KanJiaStatusEnum.SUCCESS.name().equals(kanjiaActivity.getStatus())) {
                    cartSkuVO.setPromotionId(kanjiaActivity.getId());
                    cartSkuVO.setPurchasePrice(0D);
                    throw new ServiceException(ResultCode.KANJIA_ACTIVITY_NOT_PASS_ERROR);
                }
                //砍价商品默认一件货物
                cartSkuVO.setPromotionId(kanjiaActivity.getId());
                cartSkuVO.setNum(1);
            }
        }
    }

    /**
     * 校验积分商品信息
     *
     * @param cartSkuVO 购物车信息
     */
    private void checkPoint(CartSkuVO cartSkuVO) {
        PointsGoodsVO pointsGoodsVO = promotionsClient.getPointsGoodsDetailBySkuId(cartSkuVO.getGoodsSku().getId());

        if (pointsGoodsVO != null) {
            if (walletPointClient.getUserPoint(Objects.requireNonNull(UserContext.getCurrentUser()).getExtendId()) < pointsGoodsVO.getPoints()) {
                throw new ServiceException(ResultCode.POINT_NOT_ENOUGH);
            }
            if (pointsGoodsVO.getActiveStock() < 1) {
                throw new ServiceException(ResultCode.POINT_GOODS_ACTIVE_STOCK_INSUFFICIENT);
            }
            cartSkuVO.setPoints(pointsGoodsVO.getPoints());
            cartSkuVO.setPurchasePrice(0D);
            cartSkuVO.setPromotionId(pointsGoodsVO.getId());
        }
    }

    /**
     * 校验红包商品信息
     *
     * @param cartSkuVO 购物车信息
     */
    private void checkRedPack(CartSkuVO cartSkuVO) {
        RedPackGoodsVO redPackGoodsVO = redPackGoodsClient.getRedPackGoodsDetailBySkuId(cartSkuVO.getGoodsSku().getId());

        if (redPackGoodsVO != null) {
            RedPackUser redPackUser = redPackUserClient.getRedPackUser(UserContext.getCurrentId());
            if (null == redPackUser || 0 == redPackUser.getStatus()) {
                throw new ServiceException(ResultCode.USER_RED_PACK_ERROR);
            }
            if (redPackUser.getRedPackCount() < redPackGoodsVO.getRedPack()) {
                throw new ServiceException(ResultCode.RED_PACK_NOT_ENOUGH);
            }
            if (redPackGoodsVO.getActiveStock() < 1) {
                throw new ServiceException(ResultCode.RED_PACK_GOODS_ACTIVE_STOCK_INSUFFICIENT);
            }
            cartSkuVO.setRedPack(redPackGoodsVO.getRedPack());
            cartSkuVO.setPurchasePrice(0D);
            cartSkuVO.setPromotionId(redPackGoodsVO.getId());
        }
    }


    /**
     * 检查商品促销
     *
     * @param cartParamsDTO 加入购物车参数
     * @param cartSkuVO     商品sku信息
     */
    private void checkGoodsPromotion(CartParamsDTO cartParamsDTO, CartSkuVO cartSkuVO) {
        CartSkuVO currentGoodsPromotion = promotionGoodsClient.getCurrentGoodsPromotion(cartSkuVO);
        //如果促销活动为空则直接返回
        if (currentGoodsPromotion.getPromotionMap() == null) {
            return;
        }
        cartSkuVO.setPromotionMap(currentGoodsPromotion.getPromotionMap());

        //如果加入购物车参数存在促销，则录入
        if (cartParamsDTO.getPromotionType() != null) {
            cartSkuVO.setPromotionTypeEnum(cartParamsDTO.getPromotionType());
        }
        //如果参数没有促销，又存在促销活动，则为商品设置默认促销
        else {
            //促销类型等于以下类型：
            if (cartSkuVO.getPromotionMap().keySet().stream().anyMatch(i -> i.contains(PromotionTypeEnum.SECKILL.name()))) {
                Optional<Map.Entry<String, Object>> containsPromotion =
                        cartSkuVO.getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.SECKILL.name())).findFirst();
                containsPromotion.ifPresent(stringObjectEntry -> this.setGoodsPromotionInfo(cartSkuVO, stringObjectEntry));
            }
        }

        if (cartSkuVO.getPromotionTypeEnum() != null) {
            //拼团判定
            if (cartSkuVO.getPromotionTypeEnum().equals(PromotionTypeEnum.PINTUAN)) {
                //砍价判定
                checkPintuan(cartSkuVO);
            } else if (cartSkuVO.getPromotionTypeEnum().equals(PromotionTypeEnum.KANJIA)) {
                //检测购物车的数量
                checkKanjia(cartSkuVO);
            } else if (cartSkuVO.getPromotionTypeEnum().equals(PromotionTypeEnum.POINTS_GOODS)) {
                //检测购物车的数量
                checkPoint(cartSkuVO);
            }else if (cartSkuVO.getPromotionTypeEnum().equals(PromotionTypeEnum.RED_PACK_GOODS)) {
                //检测购物车的数量
                checkRedPack(cartSkuVO);
            }
        }
    }

    /**
     * 设置商品促销信息
     *
     * @param cartSkuVO     商品sku信息
     * @param promotionInfo 促销信息
     */
    private void setGoodsPromotionInfo(CartSkuVO cartSkuVO, Map.Entry<String, Object> promotionInfo) {
        JSONObject promotionsObj = JSONUtil.parseObj(promotionInfo.getValue());
        PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
        searchParams.setSkuId(cartSkuVO.getGoodsSku().getId());
        searchParams.setPromotionId(promotionsObj.get("id").toString());
        PromotionGoods promotionsGoods = this.promotionGoodsClient.getPromotionsGoods(searchParams);
        if (promotionsGoods != null && promotionsGoods.getPrice() != null) {
            cartSkuVO.getGoodsSku().setPromotionFlag(true);
            cartSkuVO.getGoodsSku().setPromotionPrice(promotionsGoods.getPrice());
        } else {
            cartSkuVO.getGoodsSku().setPromotionFlag(false);
            cartSkuVO.getGoodsSku().setPromotionPrice(null);
        }
    }


    /**
     * 校验商品有效性，判定失效和库存，促销活动价格
     *
     * @param skuId 商品skuId
     */
    private GoodsSku checkGoods(String skuId) {
        GoodsSku dataSku = this.goodsClient.getGoodsSkuByIdFromCache(skuId);
        if (dataSku == null) {
            throw new ServiceException(ResultCode.GOODS_NOT_EXIST);
        }
        if (!GoodsAuthEnum.PASS.name().equals(dataSku.getAuthFlag()) || !GoodsMarketEnum.UPPER.name().equals(dataSku.getMarketEnable())) {
            throw new ServiceException(ResultCode.GOODS_NOT_EXIST);
        }
        if (SceneEnums.SUPPLIER.name().equals(dataSku.getScene()) && dataSku.getSupportPurchase() != null && Boolean.FALSE.equals(dataSku.getSupportPurchase())) {
            throw new ServiceException(ResultCode.GOODS_NOT_SUPPORT_PURCHASE);
        }
        return dataSku;
    }

    /**
     * 检查并设置购物车商品数量
     *
     * @param cartSkuVO 购物车商品对象
     * @param skuId     商品id
     * @param num       购买数量
     */
    private void checkSetGoodsQuantity(CartSkuVO cartSkuVO, String skuId, Integer num) {
        Integer enableStock = goodsClient.getStock(skuId);

        //如果sku的可用库存小于等于0或者小于用户购买的数量，则不允许购买
        if (enableStock <= 0 || enableStock < num) {
            throw new ServiceException(ResultCode.GOODS_SKU_QUANTITY_NOT_ENOUGH);
        }

        if (enableStock <= num) {
            cartSkuVO.setNum(enableStock);
        } else {
            cartSkuVO.setNum(num);
        }

        if (cartSkuVO.getGoodsSku() != null && !SalesModeEnum.WHOLESALE.name().equals(cartSkuVO.getGoodsSku().getSalesModel()) && cartSkuVO.getNum() > 99) {
            cartSkuVO.setNum(99);
        }
    }

    public void addBatch(List<CartParamsDTO> cartParamsDTOList) {
        if (!cartParamsDTOList.isEmpty()) {
            cartParamsDTOList.forEach(cartParamsDTO -> {
                add(cartParamsDTO);
            });
        }
    }
}
